// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Flags: --harmony-simd --harmony-tostring  --harmony-reflect
// Flags: --allow-natives-syntax --expose-natives-as natives --noalways-opt
/*
function testArithmeticOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = SIMD.Float32x4.splat(0);
  var c;

  c = a + b;
  assertEquals('Float32x4(0,0,0,0)Float32x4(0,0,0,0)', c);
  c = a++;
  assertEquals(NaN, c);
  c = a - b;
  assertEquals(NaN, c);
  c = a--;
  assertEquals(NaN, c);
  c = a * b;
  assertEquals(NaN, c);
  c = a / b;
  assertEquals(NaN, c);
  c = a % b;
  assertEquals(NaN, c);
}

testArithmeticOperators();
testArithmeticOperators();
%OptimizeFunctionOnNextCall(testArithmeticOperators);
testArithmeticOperators();


function testBitwiseOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = SIMD.Float32x4.splat(0);
  var c;
  c = a | b;
  assertEquals(0, c);
  c = a & b;
  assertEquals(0, c);
  c = a ^ b;
  assertEquals(0, c);
  c = ~a;
  assertEquals(-1, c);
  c = a << 0;
  assertEquals(0, c);
  c = a >> 0;
  assertEquals(0, c);
  c = a >>> 0;
  assertEquals(0, c);
}

testBitwiseOperators();
testBitwiseOperators();
%OptimizeFunctionOnNextCall(testBitwiseOperators);
testBitwiseOperators();


function testAssignmentOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = SIMD.Float32x4.splat(0);
  var c = a;
  c += b;
  assertEquals('Float32x4(0,0,0,0)Float32x4(0,0,0,0)', c);
  c -= b;
  assertEquals(NaN, c);
  c *= b;
  assertEquals(NaN, c);
  c /= b;
  assertEquals(NaN, c);
  c %= b;
  assertEquals(NaN, c);

  c &= b;
  assertEquals(0, c);
  c |= b;
  assertEquals(0, c);
  c ^= b;
  assertEquals(0, c);
  c <<= b;
  assertEquals(0, c);
  c >>= b;
  assertEquals(0, c);
  c >>>= b;
  assertEquals(0, c);
}

testAssignmentOperators();
testAssignmentOperators();
%OptimizeFunctionOnNextCall(testAssignmentOperators);
testAssignmentOperators();


function testStringOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = "0";
  var c = a;
  c += b;
  assertEquals("Float32x4(0,0,0,0)0", c);
  c = b + a;
  assertEquals("0Float32x4(0,0,0,0)", c);
}

testStringOperators();
testStringOperators();
%OptimizeFunctionOnNextCall(testStringOperators);
testStringOperators();


function testComparisionOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = SIMD.Float32x4.splat(0);
  assertEquals(false, a == b);
  assertEquals(true, a != b);
  assertEquals(false, a === b);
  assertEquals(true, a !== b);
  assertEquals(false, a > b);
  assertEquals(true, a >= b);
  assertEquals(false, a < b);
  assertEquals(true, a <= b);
}

testComparisionOperators();
testComparisionOperators();
// TODO(ningxin): optimized code will get opposite result.
//%OptimizeFunctionOnNextCall(testComparisionOperators);
testComparisionOperators();


function testLogicalOperators() {
  var a = SIMD.Float32x4.splat(0);
  var b = SIMD.Float32x4.splat(1);
  assertEquals(1, SIMD.Float32x4.extractLane((a && b), 0));
  assertEquals(1, SIMD.Float32x4.extractLane((a && b), 1));
  assertEquals(1, SIMD.Float32x4.extractLane((a && b), 2));
  assertEquals(1, SIMD.Float32x4.extractLane((a && b), 3));
  assertEquals(0, SIMD.Float32x4.extractLane((a || b), 0));
  assertEquals(0, SIMD.Float32x4.extractLane((a || b), 1));
  assertEquals(0, SIMD.Float32x4.extractLane((a || b), 2));
  assertEquals(0, SIMD.Float32x4.extractLane((a || b), 3));
  assertEquals(false, !a);
}

testLogicalOperators();
testLogicalOperators();
%OptimizeFunctionOnNextCall(testLogicalOperators);
testLogicalOperators();


function testConditionalOperators() {
  var a = SIMD.Int32x4.zero();
  var c = a ? 1 : 0;
  assertEquals(1, c);
}

testConditionalOperators();
testConditionalOperators();
%OptimizeFunctionOnNextCall(testConditionalOperators);
testConditionalOperators();
*/
